<?php
namespace App\Api\Controllers\QfPay;

use Dingo\Api\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class TestController
{
    public static $key = 'F45D9F4B677F4BC99CA7CE707D869527';
    private static $code = 'E2F08A8DC24D410680E2412A04ACD6A0';
    private static $mchid = 'pxlmNuOleD'; //商户号
    private static $redirect_url = '';
    private static $txcurrcd = 'CNY'; //币种 港币：HKD ；人民币：CNY


    static public function get_sign($data, $key)
    {
        ksort($data);
        $str1 = '';
        foreach ($data as $k => $v) {
            $str1 .='&'.$k . "=" . $v;
        }
        $str = $str1. $key;

        $sign = strtoupper( md5(ltrim($str, '&')));
        return [$sign, ltrim($str1, '&')];
    }


    /**
     * 请求支付接口
     *
     * @param $txamt '支付金额,单位分'
     * @param $goods_name '商品名称或标示'
     * @param $sub_openid '微信的openid'
     * @param $txdtm '请求交易时间'
     * @param $out_trade_no '订单号'
     * @param string $pay_type '支付类型：支付宝扫码:800101； 支付宝反扫:800108；支付宝服务窗：800107；微信扫码:800201； 微信刷卡:800208； 微信公众号:800207'
     * @return bool
     */
    public function payment($txamt='1', $goods_name='商品名称', $sub_openid='1245', $txdtm='2018-08-02 19:58:09', $out_trade_no='fdsdfdsa', $pay_type='800207')
    {
        $data = [
            'txamt' => $txamt,
            'mchid' => self::$mchid,
            'goods_name' => $goods_name,
            'sub_openid' => $sub_openid,
            'txdtm' => $txdtm,
            'out_trade_no' => $out_trade_no,
            'txcurrcd' => self::$txcurrcd,
            'pay_type' => $pay_type
        ];

        list($sign, $json_data) = self::get_sign($data, self::$key);
        $headers = [
            'X-QF-APPCODE' => self::$code,
            'X-QF-SIGN' => $sign
        ];
        // $url = 'https://openapi.qfpay.com/trade/v1/payment';
        $url = 'https://openapi-test.qfpay.com/trade/v1/payment';
        $headerArr = array();
        foreach( $headers as $n => $v ) {
            $headerArr[] = $n .':' . $v;
        }
        $result = json_decode( self::curlRequest($url, $json_data, $headerArr), true);

        if ($result['respcd'] == 0000) {
            $pay_params = $result['pay_params'];
            return $pay_params;
        }

        return false;
    }


    /**
     * 跳到支付页面
     *
     * @param $mchntnm
     * @param $txamt
     * @param $goods_name
     * @param $pay_params
     * @return mixed
     */
    static public function payResult($mchntnm, $txamt, $goods_name, $pay_params)
    {
        $params = [
            "mchntnm" => urlencode($mchntnm),
            "txamt" => $txamt,
            "goods_name" => urlencode($goods_name),
            "redirect_url" => urldecode(self::$redirect_url),
            "package" => $pay_params["package"],
            "timeStamp" => $pay_params["timeStamp"],
            "paySign" => urlencode($pay_params["paySign"]),
            "appId" => $pay_params["appId"],
            "nonceStr" => $pay_params["nonceStr"],
            "signType" => $pay_params["signType"]
        ];

        $url = 'https://o2.qfpay.com/q/direct';

        list($sign, $json_data) = self::get_sign($params, self::$key);

        $r = rt("", 1);
        $r["url"] = $url.'?'.$json_data;
        return  $r;
    }


    /**
     * 交易查询
     * @param $out_trade_no
     * @return mixed
     */
    public function query($out_trade_no)
    {
        $data = [
            'mchid' => self::$mchid,
            'out_trade_no' => $out_trade_no
        ];
        list($sign, $json_data) = $this->get_sign($data, self::$key);
        $headers = [
            'X-QF-APPCODE'=>self::$code,
            'X-QF-SIGN' => $sign
        ];
        $url = 'https://openapi.qfpay.com/trade/v1/query';
        $headerArr = array();
        foreach( $headers as $n => $v ) {
            $headerArr[] = $n .':' . $v;
        }
        $result = json_decode( $this->curlRequest($url, $json_data, $headerArr), true);

        return $result;
    }


    /**
     * 退款
     * @param $out_trade_no
     * @return mixed
     */
    public function refund($out_trade_no)
    {
        $data = [
            'mchid' => self::$mchid, //子商户号，标识子商户身份
            'syssn' => $trade_no, //钱方订单号，退款对应的原订单syssn
            'out_trade_no' => $out_trade_no, //外部订单号，同子商户（mchid）下，每次成功调用支付与退款接口，该参数值均不能重复使用，也不能与支付时的外部订单号相同，保证单号唯一，长度不超过128字符
            'txamt' => $total_amount, //订单支付金额，单位分
            'txdtm' => date('Y-m-d H:i:s', time()) //请求交易时间 格式为：YYYY-MM-DD HH:MM:SS
        ];
        list($sign, $json_data) = $this->get_sign($data, self::$key);
        $headers = [
            'X-QF-APPCODE'=>self::$code,
            'X-QF-SIGN' => $sign
        ];
        $url = 'https://openapi.qfpay.com/trade/v1/refund';
        $headerArr = array();
        foreach( $headers as $n => $v ) {
            $headerArr[] = $n .':' . $v;
        }
        $result = json_decode( $this->curlRequest($url, $json_data, $headerArr), true);

        return $result;
    }


    /**
     * 获取微信oauth的code
     * @param $out_trade_no
     * @return mixed
     */
    public function get_weixin_oauth_code($out_trade_no)
    {
        $data = [
            'mchid' => self::$mchid, //子商户号，标识子商户身份
            'app_code' => $app_code, //开发者识别码，由钱方分配的app_code字符串参数信息
            'redirect_uri' => $redirect_uri, //回调地址
            'sign' => $sign //根据统一签名方式得到的签名
        ];
        list($sign, $json_data) = $this->get_sign($data, self::$key);
        $headers = [
            'X-QF-APPCODE'=>self::$code,
            'X-QF-SIGN' => $sign
        ];
        $url = 'https://openapi.qfpay.com/trade/v1/get_weixin_oauth_code';
        $headerArr = array();
        foreach( $headers as $n => $v ) {
            $headerArr[] = $n .':' . $v;
        }
        $result = json_decode( $this->curlRequest($url, $json_data, $headerArr, 10, false), true);

        return $result;
    }


    /**
     * Unicode字符转换成utf8字符
     * @param string [type] $unicode_str Unicode字符
     * @return string [type]       Utf-8字符
     */
    public function unicode_to_utf8($unicode_str)
    {
        $utf8_str = '';
        $code = intval(hexdec($unicode_str));
        //这里注意转换出来的code一定得是整形，这样才会正确的按位操作
        $ord_1 = decbin(0xe0 | ($code >> 12));
        $ord_2 = decbin(0x80 | (($code >> 6) & 0x3f));
        $ord_3 = decbin(0x80 | ($code & 0x3f));
        $utf8_str = chr(bindec($ord_1)) . chr(bindec($ord_2)) . chr(bindec($ord_3));

        return $utf8_str;
    }


    static public function curlRequest($url, $params = array(), $header=array(), $time_out = 10, $is_post = true)
    {
        $ch = curl_init();//初始化curl
        curl_setopt($ch, CURLOPT_URL, $url);//抓取指定网页
        curl_setopt($ch, CURLOPT_HEADER, 0);//设置是否返回response header
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求结果为字符串且输出到屏幕上
        //当需要通过curl_getinfo来获取发出请求的header信息时，该选项需要设置为true
        curl_setopt($ch, CURLINFO_HEADER_OUT, true);

        curl_setopt($ch, CURLOPT_TIMEOUT, $time_out);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $time_out);
        curl_setopt($ch, CURLOPT_POST, $is_post);

        if ($is_post) {
            curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
        }

        if ($header) {
            curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
        }
        curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        $response = curl_exec($ch);
        //打印请求的header信息
        $request_header = curl_getinfo( $ch, CURLINFO_HEADER_OUT);
        curl_close($ch);

        return $response;
    }


}
